package main

import "log"

func adder() func(i int) int {
	sum := 0
	return func(i int) int {
		sum += i
		return sum
	}
}
func testAdder() {
	d := adder()
	for i := 0; i < 100; i++ {
		f := d(i)
		log.Println(f)
	}
}

/*
	1、定义一个函数，返回这类型是 函数类型(签名+形参)
	2、返回函数的 处理逻辑是的自增1
	3、调用函数
*/
func finonaci() func() int {
	i := 0
	fn := func() int {
		i++
		return i
	}
	return fn
}
func main() {
	/*
		1、f为一个函数类型
		2、f的主要内容是 fn,实现一个自增，当每次调用给i+1
	*/
	f := finonaci()
	log.Println(f())
	log.Println(f())
	log.Println(f())
	log.Println(f())
	log.Println(f())
	log.Println(f())
	log.Println(f())
	nimingFunc()
	log.Printf("%T", add)
	log.Printf("%T", oper)
	log.Println(add(23, 9))
	//add 为oper 的回调函数
	log.Println(oper(3, 5, add))
	//add 为oper 的回调函数
	log.Println(oper(30, 4, jian))
	//采用匿名函数执行
	r := oper(30, 4, func(i1, i2 int) int {
		return i1 * i2
	})
	log.Println(r)

}

//高阶函数
func jian(a, b int) int {
	return a - b
}

//高阶函数
func add(a, b int) int {
	return a + b
}

//add 函数
func oper(a, b int, fun func(int, int) int) int {
	println(a, b, fun)
	return fun(a, b)
}

//匿名函数
func nimingFunc() {
	/*
		在匿名行数中，如果想被调用执行的话，
		1、如果是没有参数的匿名函数，需要使用()进行调用
		2、如果是有参数的匿名函数，需要传入实参进行调用
		3、匿名函数可以进行返回结果， 返回值
		4、如果是有参数的匿名函数，没有带参数，表示是赋值给一个变量
	*/
	//一个简单的匿名函数调用
	func() {
		log.Println("我是一个匿名函数")
	}()
	//匿名有参数函数调用
	func(a, b int) {
		log.Println(a, b)
	}(2, 4)
	//函数调用并返回结果
	re := func(a, b int) int {
		return a + b
	}(2, 4)
	log.Println(re)
	//将函数赋值给一个变量
	f := func(a, b int) int {
		return a + b
	}
	log.Println(f(2, 4))
}
